home *** CD-ROM | disk | FTP | other *** search
/ Almathera Ten Pack 3: CDPD 3 / Almathera Ten on Ten - Disc 3: CDPD3.iso / scope / 101-125 / scopedisk122 / 3d / 3d.c < prev    next >
C/C++ Source or Header  |  1995-03-19  |  8KB  |  274 lines

  1. /* 3D library - By Steve Ludtke  */
  2. /* cre : 8/14/89   mod : 4/28/90 */
  3. /*       ver 1.5 (release)       */
  4. /*       Copyright 1990          */
  5.  
  6.  
  7. /*
  8.           The 3d library and all associated software in this distribution
  9.           is Copyright 1990 by Steven J. Ludtke. You have permission to
  10.           use and/or modify this code for any purpose commercial or non-
  11.           commercial with two conditions : I must be given credit in any
  12.           distributed product's documentation, and if any part of this
  13.           package is used in any commercial product (even Shareware) one
  14.           free copy of said software must be sent to me at the following
  15.           address : Steven Ludtke, 406 Yale Cir., Glenwood Springs, CO
  16.           81601; all other royalties are waived. This Copyright notice
  17.           must accompany any distributions of any part of this package,
  18.           and in general, the package should be distributed intact, with
  19.           no modifications. This notice must not be removed from the 3d.c,
  20.           test.c, and cube.c source code in this release. Modified versions
  21.           may not be distributed without permission. If the conditions
  22.           in the disclaimer are not valid in your home state, permission
  23.           to use this software is revoked.
  24. */
  25.  
  26. #define PI      3.141592
  27. #define BET(a,b,c)  (a<b && b<c)
  28. #define sqr(a)      ((a)*(a))
  29.  
  30. typedef struct { long *x,*y,*z; long *tx,*ty,*tz;} VECTOR;
  31.  
  32. /* this structure is used to sort surfaces for hidden line removal */
  33. typedef struct { long n,may; } SORTS;
  34.  
  35. typedef struct { unsigned short l; unsigned nl :1;
  36.     unsigned nc :1; unsigned nco :1; } LINES;
  37.  
  38. long xfm[3][4];             /* transformation matrix */
  39. VECTOR *V;
  40. LINES *L;
  41. short N;
  42. long REGS[12];              /* register storage for assembly ver (not done) */
  43. struct TmpRas TR;           /* TmpRas and AreaInfo for filled polygons */
  44. struct AreaInfo AI;
  45. WORD LB[500];               /* Line buffer. Polygons limited to 100 lines */
  46.  
  47. /* comparison routine for sort */
  48. int cmp(x,y)
  49. SORTS *x,*y;
  50. {
  51. return (y->may-x->may);
  52. }
  53.  
  54. /* set new x-form matrix  x,y,z is position of viewer in 3-space */
  55. /* tx,ty,tz is the viewing direction. The length of the tx,ty,tz */
  56. /* vector changes nothing. n,d are for scaling. Use rotate(v)p   */
  57. setxfm2(x,y,z,tx,ty,tz,n,d)
  58. long x,y,z;
  59. long tx,ty,tz,n,d;
  60. {
  61. if (y!=0) setxfm(atan((double)x/y),atan((double)z/sqrt((double)sqr(x)+sqr(y))),0.0,-tx,-ty,-tz,n,d);
  62. else if (x>0) setxfm(PI/2,atan((double) z/sqrt((double)sqr(x)+sqr(y))),0.0,-tx,-ty,-tz,n,d);
  63. else if (x<0) setxfm(-PI/2,atan((double) z/sqrt((double)sqr(x)+sqr(y))),0.0,-tx,-ty,-tz,n,d);
  64. else if (z>0) setxfm(0.0,-PI/2,0.0,tx,ty,tz,n,d);
  65. else setxfm(0.0,PI/2,0.0,tx,ty,tz,n,d);
  66. return(0);
  67. }
  68.  
  69. /* set new x-form matrix  a1=x/y  a2=z/xy  a3=z'/x'y' (see Goldstein 146) */
  70. /* tx,ty,tz are translsations after rotation. n,d are for scaling.        */
  71. setxfm(a1,a2,a3,tx,ty,tz,n,d)
  72. double a1,a2,a3;
  73. long tx,ty,tz,n,d;
  74. {
  75. xfm[0][0]=(long) (( cos(a3)*cos(a1)-cos(a2)*sin(a1)*sin(a3))*REZ)*n/d;
  76. xfm[1][0]=(long) ((-sin(a3)*cos(a1)-cos(a2)*sin(a1)*cos(a3))*REZ)*n/d;
  77. xfm[2][0]=(long) ( sin(a2)*sin(a1)*REZ)*n/d;
  78. xfm[0][1]=(long) (( cos(a3)*sin(a1)+cos(a2)*cos(a1)*sin(a3))*REZ)*n/d;
  79. xfm[1][1]=(long) ((-sin(a3)*sin(a1)+cos(a2)*cos(a1)*cos(a3))*REZ)*n/d;
  80. xfm[2][1]=(long) (-sin(a2)*cos(a1)*REZ)*n/d;
  81. xfm[0][2]=(long) ( sin(a3)*sin(a2)*REZ)*n/d;
  82. xfm[1][2]=(long) ( cos(a3)*sin(a2)*REZ)*n/d;
  83. xfm[2][2]=(long) ( cos(a2)*REZ)*n/d;
  84. xfm[0][3]=tx;
  85. xfm[1][3]=ty;
  86. xfm[2][3]=tz;
  87. return(0);
  88. }
  89.  
  90. /* rotate without perspective */
  91. rotate(v,n)
  92. VECTOR *v;
  93. int n;
  94. {
  95. int i;
  96.  
  97. for (i=0; i<n; i++) {
  98. v->ty[i]=(v->x[i]*xfm[1][0]+v->y[i]*xfm[1][1]+v->z[i]*xfm[1][2])/REZ+xfm[1][3];
  99. v->tx[i]=((v->x[i]*xfm[0][0]+v->y[i]*xfm[0][1]+v->z[i]*xfm[0][2])/REZ+xfm[0][3])*ASPECT+XCEN;
  100. v->tz[i]=((v->x[i]*xfm[2][0]+v->y[i]*xfm[2][1]+v->z[i]*xfm[2][2])/REZ+xfm[2][3])+YCEN;
  101. }
  102. return(0);
  103. }
  104.  
  105. /* rotate pre-translate. Use with setxfm2 */
  106. rotatep(v,n)
  107. VECTOR *v;
  108. int n;
  109. {
  110. long i,j,x,y;
  111. for (i=0; i<n; i++) {
  112. v->tx[i]=v->x[i]+xfm[0][3];
  113. v->ty[i]=v->y[i]+xfm[1][3];
  114. v->tz[i]=v->z[i]+xfm[2][3];
  115. y=(v->tx[i]*xfm[1][0]+v->ty[i]*xfm[1][1]+v->tz[i]*xfm[1][2])/REZ;
  116. x=((v->tx[i]*xfm[0][0]+v->ty[i]*xfm[0][1]+v->tz[i]*xfm[0][2])/REZ)*ASPECT+XCEN;
  117. v->tz[i]=((v->tx[i]*xfm[2][0]+v->ty[i]*xfm[2][1]+v->tz[i]*xfm[2][2])/REZ)+YCEN;
  118. v->ty[i]=y;
  119. v->tx[i]=x;
  120. }
  121. return(0);
  122. }
  123.  
  124.  
  125. /* rotate with perspective, pre-translate. Use with setxfm2 */
  126. rotatevp(v,n)
  127. VECTOR *v;
  128. int n;
  129. {
  130. long i,j,x,y;
  131. for (i=0; i<n; i++) {
  132. v->tx[i]=v->x[i]+xfm[0][3];
  133. v->ty[i]=v->y[i]+xfm[1][3];
  134. v->tz[i]=v->z[i]+xfm[2][3];
  135. if (0==(y=(v->tx[i]*xfm[1][0]+v->ty[i]*xfm[1][1]+v->tz[i]*xfm[1][2])/REZ)) y= -1;
  136. j=D3VDIST+ y;
  137. if (j==0) j=1;
  138. x=((v->tx[i]*xfm[0][0]+v->ty[i]*xfm[0][1]+v->tz[i]*xfm[0][2])/REZ*D3VDIST)/j*ASPECT+XCEN;
  139. v->tz[i]=((v->tx[i]*xfm[2][0]+v->ty[i]*xfm[2][1]+v->tz[i]*xfm[2][2])/REZ*D3VDIST)/j+YCEN;
  140. v->ty[i]=y;
  141. v->tx[i]=x;
  142. }
  143. return(0);
  144. }
  145.  
  146. /* rotate with perspective */
  147. rotatev(v,n)
  148. VECTOR *v;
  149. int n;
  150. {
  151. long i,j;
  152. for (i=0; i<n; i++) {
  153. if (0==(v->ty[i]=(v->x[i]*xfm[1][0]+v->y[i]*xfm[1][1]+v->z[i]*xfm[1][2])/REZ+xfm[1][3])) v->ty[i]= -1;
  154. j=D3VDIST+ v->ty[i];
  155. if (j==0) j=1;
  156. v->tx[i]=((v->x[i]*xfm[0][0]+v->y[i]*xfm[0][1]+v->z[i]*xfm[0][2])/REZ+xfm[0][3])*D3VDIST/j*ASPECT+XCEN;
  157. v->tz[i]=((v->x[i]*xfm[2][0]+v->y[i]*xfm[2][1]+v->z[i]*xfm[2][2])/REZ+xfm[2][3])*D3VDIST/j+YCEN;
  158. }
  159. return(0);
  160. }
  161.  
  162. /* set up 1 - 4 rastports for filled shape drawing */
  163. Init3Ras(rp,rp2,rp3,rp4)
  164. struct RastPort *rp,*rp2,*rp3,*rp4;
  165. {
  166. PLANEPTR buf;
  167. InitArea(&AI,&LB,200);
  168. rp->AreaInfo=&AI;
  169. if (rp2!=NULL) rp2->AreaInfo=&AI;
  170. if (rp3!=NULL) rp3->AreaInfo=&AI;
  171. if (rp4!=NULL) rp4->AreaInfo=&AI;
  172. buf=(PLANEPTR)AllocRaster(XHI,YHI);
  173. InitTmpRas(&TR,buf,RASSIZE(XHI,YHI));
  174. rp->TmpRas=&TR;
  175. if (rp2!=NULL) rp2->TmpRas=&TR;
  176. if (rp3!=NULL) rp3->TmpRas=&TR;
  177. if (rp4!=NULL) rp4->TmpRas=&TR;
  178. return(0);
  179. }
  180.  
  181. /* free memory allocated by Init3Ras */
  182. Exit3d(rp)
  183. struct RastPort *rp;
  184. {
  185. FreeRaster(rp->TmpRas->RasPtr,XHI,YHI);
  186. return(0);
  187. }
  188.  
  189. /* draw outlines of 3d shapes */
  190. d3lines(v,l,n,rp)
  191. VECTOR *v;
  192. int n;
  193. LINES *l;
  194. struct RastPort *rp;
  195. {
  196. int i,flag;
  197.  
  198. flag=0;
  199. for (i=0; i<n; i++) {
  200.  
  201. while (l[i].nc || l[i].nco) {                    /* change colors if necc. */
  202.     if (l[i].nco) SetAPen(rp,l[i].l);
  203.     i++;
  204.     }
  205. if (v->tx[l[i].l]>XLO && v->tx[l[i].l]<XHI &&    /* clip to defined region */
  206.     v->tz[l[i].l]>YLO && v->tz[l[i].l]<YHI ) {
  207. if (l[i].nl) { Move(rp,v->tx[l[i].l],YHI-v->tz[l[i].l]+YLO); flag=0; }
  208. else {
  209.     if (v->ty[l[i].l]<0) flag=1;
  210.     else if (flag==1) { Move(rp,v->tx[l[i].l],YHI-v->tz[l[i].l]+YLO); flag=0; }
  211.     else Draw(rp,v->tx[l[i].l],YHI-v->tz[l[i].l]+YLO);
  212.     }
  213. }
  214. else flag=1;
  215.  
  216. }
  217. return(0);
  218. }
  219.  
  220. /* draw filled 3d shapes with hidden line removal */
  221. d3surf(v,l,n,rp)
  222. VECTOR *v;
  223. LINES *l;
  224. int n;
  225. struct RastPort *rp;
  226. {
  227. int i,j,flag,c;
  228. int cmp();
  229. SORTS s[100],m;
  230.  
  231. c= -1;
  232. for (i=0; i<n; i++) {                                /* set up SORTS for */
  233.     if (l[i].nl)  {
  234.         if (c>=0) s[c].may=s[c].may/(i-s[c].n);
  235.         c++;
  236.         s[c].n=i;
  237.         s[c].may=0;
  238.         }
  239.     if (!(l[i].nc || l[i].nco)) s[c].may+=v->ty[l[i].l];
  240.     }
  241. s[c].may=s[c].may/(i-s[c].n);
  242. L=l; V=v; N=n;
  243. flag=0;
  244.  
  245. qsort(s,c+1,sizeof(SORTS),&cmp);
  246.  
  247. for (j=0; j<c+1; j++) {                            /* draw shapes in order */
  248. flag=0;
  249. i=s[j].n;
  250. while(!l[i].nl && i!=n || i==s[j].n) {
  251. while (l[i].nc || l[i].nco) {
  252.     if (l[i].nc) SetAPen(rp,l[i].l);
  253.     if (l[i].nco) SetOPen(rp,l[i].l);
  254.     i++;
  255.     }
  256. if (v->tx[l[i].l]>XLO && v->tx[l[i].l]<XHI &&
  257.     v->tz[l[i].l]>YLO && v->tz[l[i].l]<YHI ) {
  258. if (l[i].nl) { AreaMove(rp,v->tx[l[i].l],YHI-v->tz[l[i].l]+YLO); flag=0; }
  259. else {
  260.     if (v->ty[l[i].l]<0) flag=1;
  261.     else if (flag==1) { AreaMove(rp,v->tx[l[i].l],YHI-v->tz[l[i].l]+YLO); flag=0; }
  262.     else AreaDraw(rp,v->tx[l[i].l],YHI-v->tz[l[i].l]+YLO);
  263.     }
  264. }
  265. else flag=1;
  266. i++;
  267. }
  268. AreaEnd(rp);
  269.  
  270. }
  271. return(0);
  272. }
  273.  
  274.